package com.atguigu.gmall.item.service.impl;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.item.feign.GmallPmsClient;
import com.atguigu.gmall.item.feign.GmallSmsClient;
import com.atguigu.gmall.item.feign.GmallWmsClient;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.item.vo.ItemVo;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.vo.ItemGroupVo;
import com.atguigu.gmall.pms.vo.SaleAttrValueVo;
import com.atguigu.gmall.sms.vo.ItemSaleVo;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private GmallPmsClient pmsClient;

    @Autowired
    private GmallWmsClient wmsClient;

    @Autowired
    private GmallSmsClient smsClient;

    @Autowired
    private ExecutorService executorService;

    @Autowired
    private TemplateEngine templateEngine;

    @Override
    public ItemVo loadData(Long skuId) {
        ItemVo itemVo = new ItemVo();
        CompletableFuture<SkuEntity> skuEntityFuture = CompletableFuture.supplyAsync(() -> {
            // 1.根据skuId查询sku
            ResponseVo<SkuEntity> skuResponseVo = pmsClient.querySkuById(skuId);
            SkuEntity skuEntity = skuResponseVo.getData();
            if (skuEntity == null) {
                throw new RuntimeException("您要访问的商品不存在!");
            }
            itemVo.setSkuId(skuId);
            itemVo.setTitle(skuEntity.getTitle());
            itemVo.setSubtitle(skuEntity.getSubtitle());
            itemVo.setPrice(skuEntity.getPrice());
            itemVo.setWeight(skuEntity.getWeight());
            itemVo.setDefaultImage(skuEntity.getDefaultImage());
            return skuEntity;
        }, executorService);


        CompletableFuture<Void> categoryFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 2.根据三级分类Id查询一二三级分类
            ResponseVo<List<CategoryEntity>> categoriesResponseVo = pmsClient.queryCategoriesByCid(skuEntity.getCategoryId());
            List<CategoryEntity> categoryEntities = categoriesResponseVo.getData();
            itemVo.setCategories(categoryEntities);
        }, executorService);

        CompletableFuture<Void> brandFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 3.根据品牌id查询品牌
            ResponseVo<BrandEntity> brandResponseVo = pmsClient.queryBrandById(skuEntity.getBrandId());
            BrandEntity brandEntity = brandResponseVo.getData();
            if (brandEntity != null) {
                itemVo.setBrandId(brandEntity.getId());
                itemVo.setBrandName(brandEntity.getName());
            }
        }, executorService);

        CompletableFuture<Void> spuEntityFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 4.根据spuId查询spu
            ResponseVo<SpuEntity> spuResponseVo = pmsClient.querySpuById(skuEntity.getSpuId());
            SpuEntity spuEntity = spuResponseVo.getData();
            itemVo.setSpuId(spuEntity.getId());
            itemVo.setSpuName(spuEntity.getName());
        }, executorService);

        CompletableFuture<Void> skuImagesFuture = CompletableFuture.runAsync(() -> {
            // 5.根据skuId查询sku的图片列表
            ResponseVo<List<SkuImagesEntity>> imagesResponseVo = pmsClient.queryImagesBySkuId(skuId);
            List<SkuImagesEntity> skuImagesEntities = imagesResponseVo.getData();
            if (!CollectionUtils.isEmpty(skuImagesEntities)) {
                itemVo.setImages(skuImagesEntities);
            }
        }, executorService);

        CompletableFuture<Void> salesFuture = CompletableFuture.runAsync(() -> {
            // 6.根据skuId查询营销信息（积分 满减 打折）
            ResponseVo<List<ItemSaleVo>> salesResponseVo = smsClient.queryItemSalesBySkuId(skuId);
            List<ItemSaleVo> itemSaleVos = salesResponseVo.getData();
            itemVo.setSales(itemSaleVos);
        }, executorService);

        CompletableFuture<Void> wareSkuFuture = CompletableFuture.runAsync(() -> {
            // 7.根据skuid查询库存
            ResponseVo<List<WareSkuEntity>> wareResponseVo = wmsClient.queryWareSkusBySkuId(skuId);
            List<WareSkuEntity> wareSkuEntities = wareResponseVo.getData();
            if (!CollectionUtils.isEmpty(wareSkuEntities)) {
                itemVo.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0));
            }
        }, executorService);

        CompletableFuture<Void> baseAttrFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 8.根据spuId查询spu下所有sku的销售属性
            ResponseVo<List<SaleAttrValueVo>> saleAttrResponseVo = pmsClient.querySaleAttrValuesBySupId(skuEntity.getSpuId());
            List<SaleAttrValueVo> saleAttrValueVos = saleAttrResponseVo.getData();
            if (!CollectionUtils.isEmpty(saleAttrValueVos)) {
                itemVo.setSaleAttrs(saleAttrValueVos);
            }
        }, executorService);

        CompletableFuture<Void> saleAttrFuture = CompletableFuture.runAsync(() -> {
            // 9.根据skuId查询当前sku的销售属性 {3: 暗夜黑, 4: 8G, 5: 256G}
            ResponseVo<List<SkuAttrValueEntity>> skuAttrResponseVo = pmsClient.querySkuAttrsBySkuId(skuId);
            List<SkuAttrValueEntity> skuAttrValues = skuAttrResponseVo.getData();
            //将实体类转换为map结构
            if (!CollectionUtils.isEmpty(skuAttrValues)) {
                itemVo.setSaleAttr(skuAttrValues.stream().collect(Collectors.toMap(SkuAttrValueEntity::getAttrId, SkuAttrValueEntity::getAttrValue)));
            }
        }, executorService);

        CompletableFuture<Void> mappingFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 10.根据spuId查询spu下所有销售属性组合与skuId的映射关系
            ResponseVo<String> mappingResponseVo = pmsClient.queryMappingBySpuId(skuEntity.getSpuId());
            String mappingStr = mappingResponseVo.getData();
            itemVo.setSkuJsons(mappingStr);
        }, executorService);

        CompletableFuture<Void> spuDescFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 11.根据spuId查询spu的海报信息
            ResponseVo<SpuDescEntity> spuDescEntityResponseVo = pmsClient.querySpuDescById(skuEntity.getSpuId());
            SpuDescEntity spuDescEntity = spuDescEntityResponseVo.getData();
            if (spuDescEntity != null) {
                //https://hufufu-gmall.oss-cn-shanghai.aliyuncs.com/2022-12-27/67bd90f1-891b-4d28-81ff-1140ff9b6dc0_u=2303291280,1230118124&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto.webp
                //https://hufufu-gmall.oss-cn-shanghai.aliyuncs.com/2022-12-27/ad397250-b1c0-417c-8576-8da291f9e220_u=3617994505,640480494&fm=253&fmt=auto&app=138&f=JPEG.webp
                List<String> imagesUrl = Arrays.asList(StringUtils.split(spuDescEntity.getDecript(), ";"));
                itemVo.setSpuImages(imagesUrl);
            }
        }, executorService);

        CompletableFuture<Void> groupFuture = skuEntityFuture.thenAcceptAsync(skuEntity -> {
            // 12.查询规格参数分组及组下的规格参数和值
            ResponseVo<List<ItemGroupVo>> groupsResponseVo = pmsClient.queryGroupWithAttrValueByCidAndSkuIdAndSpuId(skuEntity.getCategoryId(), skuId, skuEntity.getSpuId());
            List<ItemGroupVo> itemGroupVos = groupsResponseVo.getData();
            itemVo.setGroups(itemGroupVos);
        }, executorService);

        //等待所有线程执行完毕才返回结果
        CompletableFuture.allOf(categoryFuture,brandFuture,spuEntityFuture,skuImagesFuture,salesFuture,wareSkuFuture,
                baseAttrFuture,saleAttrFuture,mappingFuture,spuDescFuture,groupFuture).join();

        //异步生成静态页面
        executorService.execute(()->{
            this.generateHtml(itemVo);
        });

        return itemVo;
    }

    //生成静态页面
    private void generateHtml(ItemVo itemVo){

        //生成静态页面的文件流
        try (PrintWriter printWriter = new PrintWriter("E:\\staticHtml\\html\\"+itemVo.getSkuId()+".html")){

            //上下文对象，通过它可以将数据传送给模板引擎
            Context context = new Context();
            context.setVariable("itemVo",itemVo);
            templateEngine.process("item",context,printWriter);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        CompletableFuture.supplyAsync(()->{
            System.out.println("CompletableFuture初始化多线程任务"+Thread.currentThread().getName());
            return "hello CompletableFuture";
        }).thenApplyAsync((t)->{ //可以获取上一个任务的返回结果集 并有自己的返回结果集
            System.out.println("=================thenApplyAsync=================="+Thread.currentThread().getName());
            System.out.println("上一个任务的返回结果集"+t);
            return "hello thenApplyAsync ";
        }).thenAcceptAsync(t->{ //可以获取上一个任务的返回结果集 没有自己的返回结果集
            System.out.println("============thenApplyAsync==================="+Thread.currentThread().getName());
            System.out.println("上一个任务的返回结果集"+t);
        }).thenRunAsync(()->{ //无法获取上一个任务的返回结果集 也没有自己的返回结果集
            System.out.println("============thenRunAsync==================="+Thread.currentThread().getName());
        });

//        CompletableFuture.supplyAsync(()->{
//            System.out.println("CompletableFuture初始化多线程任务"+Thread.currentThread().getName());
//            int i = 1/0;
//            return "hello CompletableFuture";
//        }).whenCompleteAsync((t,u)->{ //不管是否异常都会执行
//            System.out.println("======================whenCompleteAsync======================");
//            System.out.println("上一个任务的执行结果"+t);
//            System.out.println("上一个任务的异常信息"+u);
//        }).exceptionally(t->{
//            System.out.println("=======================exceptionally==========================");
//            System.out.println("上一个任务的异常信息"+t);
//            return "exceptionally";
//        });
//
//        System.out.println("这是main方法执行了"+Thread.currentThread().getName());
//        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
//        new Thread(futureTask).start();
//        try {
//
//            System.out.println("3异步任务返回结果集"+futureTask.get());
//        } catch (Exception e) {
//            e.printStackTrace();
//            System.out.println("4异步任务异常信息"+e.getMessage());
//        }
//        System.out.println("1执行mian方法"+Thread.currentThread().getName());
    }
}

class MyCallable implements Callable<String>{
    @Override
    public String call() throws Exception {
        System.out.println("2实现了callable接口完成多线程编程"+Thread.currentThread().getName());
        return "hello callable";
    }
}